package com.tomato.modules.id.service.impl;

import com.tomato.api.id.dataobject.TomatoIdDO;
import com.tomato.modules.id.constants.TomatoIdConstants;
import com.tomato.modules.id.mapper.TomatoIdMapper;
import com.tomato.modules.id.po.SegmentId;
import com.tomato.modules.id.service.SegmentIdService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 分布式 ID
 *
 * @author lizhifu
 * @date 2022/3/17
 */
@Service
public class SegmentIdServiceImpl implements SegmentIdService {
    private static final Logger logger = LoggerFactory.getLogger(SegmentIdServiceImpl.class);
    @Resource
    private TomatoIdMapper tomatoIdMapper;

    /**
     * query和update使用的是同一连接，保障重试 tomatoIdMapper.selectByBizType(bizType) 结果是最新的
     * @param bizType
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public SegmentId updateMaxId(String bizType) {
        for (int i = 0; i < TomatoIdConstants.RETRY; i++) {
            TomatoIdDO oldTomatoIdDO = tomatoIdMapper.selectByBizType(bizType);
            if (oldTomatoIdDO == null) {
                throw new RuntimeException("业务类型不存在 :" + bizType);
            }
            int row = tomatoIdMapper.updateMaxId(bizType, oldTomatoIdDO.getVersion());
            if(row != 1){
                logger.info("更新 maxId 失败，重试次数：{} 数据:{}",i, oldTomatoIdDO);
                continue;
            }
            logger.info("更新 maxId 成功，重试次数：{} 数据:{}",i, oldTomatoIdDO);
            return SegmentId.buildTomatoId(oldTomatoIdDO);
        }
        throw new RuntimeException("更新 maxId 失败，重试次数 3 " + bizType);
    }
}
